﻿using System.Diagnostics;
using System.Runtime.InteropServices;
using PCLLearning.Framework.Models;

namespace PCLLearning.Framework
{
    public abstract class Win32API
    {
        private const int MB_ICONERROR = 0x00000010;
        private const int MB_OKCANCEL = 0x00000001;
        private const int MB_ICONWARNING = 0x00000030;

        #region BrowseInfo ulFlags


        private const int BIF_NEWDIALOGSTYLE = 0x00000040;

        private const int BIF_RETURNONLYFSDIRS = 0x00000001;

        #endregion

        #region OpenFileName

        private static readonly string OpenFileName_MaxFile = new String(new char[256]);
        private static readonly string OpenFileName_FileTitle = new String(new char[64]);
        private const int OFN_EXPLORER = 0x00080000;
        private const int OFN_FILEMUSTEXIST = 0x00001000;
        private const int OFN_PATHMUSTEXIST = 0x00000800;
        private const int OFN_NOCHANGEDIR = 0x00000008;

        #endregion

        #region System Menue

        /// <summary>
        /// 最小化
        /// </summary>
        const int SW_SHOWMINIMIZED = 2;

        /// <summary>
        /// 最大化
        /// </summary>
        const int SW_SHOWMAXIMIZED = 3;

        /// <summary>
        /// 还原
        /// </summary>
        const int SW_SHOWRESTORE = 1;

        /// <summary>
        /// 窗口风格
        /// </summary>
        const int GWL_STYLE = -16;
        /// <summary>
        /// 标题栏
        /// </summary>
        const int WS_CAPTION = 0x00c00000;
        /// <summary>
        /// 标题栏按钮
        /// </summary>
        const int WS_SYSMENU = 0x00080000;

        #endregion

        [DllImport("user32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
        private static extern int MessageBox(IntPtr hWhd, string text, string caption, int type);

        [DllImport("Comdlg32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
        private static extern bool GetOpenFileName([In, Out] OpenFileName openFileName);

        [DllImport("shell32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
        private static extern IntPtr SHBrowseForFolder([In, Out] BrowseInfo browseInfo);

        [DllImport("shell32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
        private static extern IntPtr SHGetPathFromIDList([In] IntPtr pidl, [In, Out] char[] pszPath);

        [DllImport("user32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
        public static extern IntPtr GetForegroundWindow();

        [DllImport("user32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
        private static extern long GetWindowLong(IntPtr hwd, int nIndex);


        [DllImport("user32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
        private static extern void SetWindowLong(IntPtr hwd, int nIndex, long dwNewLong);

        [DllImport("user32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
        public static extern bool ShowWindow(IntPtr hwd, int cmdShow);

        public static int ErrorMessageBox(string message, string title = null)
        {
            return MessageBox(IntPtr.Zero, message, title, MB_ICONERROR);
        }

        public static int ConfirmMessageBox(string message, string title = null)
        {
            return MessageBox(IntPtr.Zero, message, title, MB_OKCANCEL + MB_ICONWARNING);
        }

        public static string GetPathFromWindowsExplorer(string dialogTitle)
        {
            try
            {
                var browseInfo = new BrowseInfo()
                {
                    pszDisplayName = new string(new char[2048]),
                    lpszTitle = dialogTitle,
                    ulFlags = BIF_NEWDIALOGSTYLE,
                    pidlRoot = IntPtr.Zero
                };
                var pidlPath = SHBrowseForFolder(browseInfo);
                var pathChars = new char[2048];
                Array.Fill(pathChars, '\n');
                SHGetPathFromIDList(pidlPath, pathChars);
                var path = new string(pathChars);
                return path.Substring(0, path.IndexOf('\n'));
            }
            catch (Exception exception)
            {
                Debug.WriteLine(exception);
            }

            return String.Empty;
        }

        public static string? OpenFile(string filter)
        {
            try
            {
                var openFileName = new OpenFileName();
                openFileName.structSize = Marshal.SizeOf(openFileName);
                openFileName.filter = filter;
                openFileName.file = OpenFileName_MaxFile;
                openFileName.maxFile = OpenFileName_MaxFile.Length;
                openFileName.fileTitle = OpenFileName_FileTitle;
                openFileName.maxFileTitle = OpenFileName_FileTitle.Length;
                openFileName.initialDir = Environment.CurrentDirectory.Replace("/", "\\");
                openFileName.title = "选择文件";
                openFileName.flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_NOCHANGEDIR;
                if (GetOpenFileName(openFileName))
                {
                    return openFileName.file;
                }
            }
            catch (Exception exception)
            {
                Debug.WriteLine(exception);
            }
            return null;
        }

        public static void ShowTitleBar(IntPtr hwd)
        {
            var wl = GetWindowLong(hwd, GWL_STYLE);
            wl |= WS_CAPTION;
            SetWindowLong(hwd, GWL_STYLE, wl);
        }

        public static void HiddenTitleBar(IntPtr hwd)
        {
            var wl = GetWindowLong(hwd, GWL_STYLE);
            wl &= ~WS_CAPTION;
            SetWindowLong(hwd, GWL_STYLE, wl);
        }

        public static void ShowCloseButton(IntPtr hwd)
        {
            var wl = GetWindowLong(hwd, GWL_STYLE);
            wl |= WS_SYSMENU;
            SetWindowLong(hwd, GWL_STYLE, wl);
        }
    }
}
